using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using HengTong.Model;
using HengTong.Model.Db.Hr;
using HengTong.ViewModel.Person.SysPersonVms;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using TiaoTaoHelper.Models;
using TiaoTaoHelper.Wtm.Attributes;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Mvc;

namespace HengTong.Areas.Person.Controllers;

public partial class SysPersonController(IMemoryCache memoryCache)
{
    [ActionDescription("Sys.Import")]
    [HttpPost("Import")]
    public async Task<ActionResult> Import(SysPersonImportVm vm)
    {
        if (vm != null && (vm.ErrorListVM.EntityList.Count > 0 || !(await vm.BatchSaveDataAsync())))
        {
            return BadRequest(ModelState.GetErrorJson());
        }
        else
        {
            return Ok(vm?.EntityList?.Count ?? 0);
        }
    }

    //人员档案生成系统账号
    [HttpPost("CreateAccounts")]
    [ActionDescription("生成系统账号")]
    public async Task<Result<int>> CreateAccounts(string[] ids)
    {
        var vm = Wtm.CreateVM<SysPersonBatchVm>();
        if (ids != null && ids.Any())
        {
            vm.Ids = ids;
        }
        else
        {
            return new Result<int>("请选择要生成账号的员工档案");
        }

        return await vm.CreateAccountsAsync();
    }

    //接口1：通过人员档案的查询条件里的数据，直接一键生成人员补录数据草稿状态的，包括子表，接口2：通过勾选ids，直接一键生成人员补录数据草稿状态的，包括子表

    /// <summary>
    /// 通过查询条件一键生成人员补录数据（草稿状态）
    /// </summary>
    /// <param name="searcher">查询条件</param>
    /// <returns>生成的数据数量</returns>
    [HttpPost("GenSuppBySearch")]
    [ActionDescription("查询条件生成补录数据")]
    [PreventDuplicateSubmit]
    public async Task<Result<int>> GenSuppBySearch(SysPersonSearcher searcher)
    {
        var vm = Wtm.CreateVM<SysPersonBatchVm>();
        return await vm.GenSuppBySearchAsync(searcher);
    }

    /// <summary>
    /// 通过勾选ID一键生成人员补录数据（草稿状态）
    /// </summary>
    /// <param name="ids">勾选的人员档案ID</param>
    /// <returns>生成的数据数量</returns>
    [HttpPost("GenSuppByIds")]
    [ActionDescription("勾选ID生成补录数据")]
    [PreventDuplicateSubmit]
    public async Task<Result<int>> GenSuppByIds(string[] ids)
    {
        var vm = Wtm.CreateVM<SysPersonBatchVm>();

        if (ids != null && ids.Any())
        {
            vm.Ids = ids;
        }
        else
        {
            return new Result<int>("请选择需要生成补录数据的人员档案");
        }

        return await vm.GenSuppByIdsAsync();
    }

    /// <summary>
    /// 获取统计数据（饼图）
    /// </summary>
    /// <returns></returns>
    [HttpGet("GetPieStatistics")]
    [ActionDescription("获取统计数据(饼图)")]
    public async Task<Dictionary<string, Dictionary<string, int>>> GetStatistics()
    {
        // 在职员工年龄分布
        var ageRange = new Dictionary<string, int>
        {
            { "18-29", 0 },
            { "30-39", 0 },
            { "40-49", 0 },
            { "50-59", 0 },
            { "60+", 0 }
        };
        foreach (var age in ageRange)
        {
            switch (age.Key)
            {
                case "18-29":
                    ageRange[age.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => e.Age.Value >= 18 && e.Age.Value <= 29 && e.State == PersonState.在职)
                        .CountAsync();
                    break;
                case "30-39":
                    ageRange[age.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => e.Age.Value >= 30 && e.Age.Value <= 39 && e.State == PersonState.在职)
                        .CountAsync();
                    break;
                case "40-49":
                    ageRange[age.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => e.Age.Value >= 40 && e.Age.Value <= 49 && e.State == PersonState.在职)
                        .CountAsync();
                    break;
                case "50-59":
                    ageRange[age.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => e.Age.Value >= 50 && e.Age.Value <= 59 && e.State == PersonState.在职)
                        .CountAsync();
                    break;
                case "60+":
                    ageRange[age.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => e.Age.Value >= 60 && e.State == PersonState.在职)
                        .CountAsync();
                    break;
            }
        }

        // 在职员工学历分布
        var eduRange = new Dictionary<string, int>
        {
            { "初中及以下", 0 },
            { "高中/中专", 0 },
            { "大专", 0 },
            { "本科", 0 },
            { "硕士及以上", 0 }
        };
        foreach (var edu in eduRange)
        {
            switch (edu.Key)
            {
                case "初中及以下":
                    eduRange[edu.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => (e.HighestEducation == EducationLevel.初中 || e.HighestEducation == null ||
                                     e.HighestEducation == EducationLevel.其他) && e.State == PersonState.在职)
                        .CountAsync();
                    break;
                case "高中/中专":
                    eduRange[edu.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e =>
                            (e.HighestEducation == EducationLevel.中专 || e.HighestEducation == EducationLevel.高中) &&
                            e.State == PersonState.在职)
                        .CountAsync();
                    break;
                case "大专":
                    eduRange[edu.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => e.HighestEducation == EducationLevel.大专 && e.State == PersonState.在职)
                        .CountAsync();
                    break;
                case "本科":
                    eduRange[edu.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => e.HighestEducation == EducationLevel.本科 && e.State == PersonState.在职)
                        .CountAsync();
                    break;
                case "硕士及以上":
                    eduRange[edu.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => (e.HighestEducation == EducationLevel.硕士 ||
                                     e.HighestEducation == EducationLevel.博士 ||
                                     e.HighestEducation == EducationLevel.博士后 ||
                                     e.HighestEducation == EducationLevel.博士研究生) && e.State == PersonState.在职)
                        .CountAsync();
                    break;
            }
        }

        // 在职状态分布
        var stateRange = new Dictionary<string, int>
        {
            { "试用期", 0 },
            { "在职", 0 },
            { "离职", 0 },
            { "退休", 0 }
        };
        foreach (var state in stateRange)
        {
            switch (state.Key)
            {
                case "试用期":
                    stateRange[state.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => e.State == PersonState.试用期)
                        .CountAsync();
                    break;
                case "在职":
                    stateRange[state.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => e.State == PersonState.在职)
                        .CountAsync();
                    break;
                case "离职":
                    stateRange[state.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => e.State == PersonState.离职)
                        .CountAsync();
                    break;
                case "退休":
                    stateRange[state.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => e.State == PersonState.退休)
                        .CountAsync();
                    break;
            }
        }

        // 在职员工性别分布
        var genderRange = new Dictionary<string, int>
        {
            { "男", 0 },
            { "女", 0 },
            { "未知", 0 }
        };
        foreach (var gender in genderRange)
        {
            switch (gender.Key)
            {
                case "男":
                    genderRange[gender.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => e.Gender == Gender.男 && e.State == PersonState.在职)
                        .CountAsync();
                    break;
                case "女":
                    genderRange[gender.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => e.Gender == Gender.女 && e.State == PersonState.在职)
                        .CountAsync();
                    break;
                case "未知":
                    genderRange[gender.Key] = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .Where(e => (e.Gender == null || e.Gender == Gender.其他) && e.State == PersonState.在职)
                        .CountAsync();
                    break;
            }
        }

        var data = new Dictionary<string, Dictionary<string, int>>()
        {
            { "员工年龄分布", ageRange },
            { "最高学历分布", eduRange },
            { "在职状态分布", stateRange },
            { "员工性别分布", genderRange }
        };
        return data;
    }


    /// <summary>
    /// 获取统计数据 (数据)
    /// </summary>
    /// <returns></returns>
    [HttpGet("GetStatisticsData")]
    [ActionDescription("获取统计数据(数据)")]
    public async Task<Dictionary<string, int>> GetStatisticsData()
    {
        DateTime monthEnd = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(1);
        var raw = await DC.Set<SysPerson>()
            .Where(x => x.GetType() == typeof(SysPerson))
            .Select(e => new
            {
                e.State,
                e.HireDate,
                e.BirthDate,
                e.Gender
            })
            .ToArrayAsync();

        // 计算待退休员工数量：本月末男性年龄大于60周岁或女性大于50周岁的在职员工
        var retirementCount = raw.Count(e =>
            e.State == PersonState.在职 &&
            e.BirthDate.HasValue &&
            ((e.Gender == Gender.男 && CalculateAgeAtDate(e.BirthDate.Value, monthEnd) > 60) ||
             (e.Gender == Gender.女 && CalculateAgeAtDate(e.BirthDate.Value, monthEnd) > 50)));

        var data = new Dictionary<string, int>()
        {
            { "在职员工数量", raw.Count(e => e.State == PersonState.在职) },
            { "试用期员工数量", raw.Count(e => e.State == PersonState.试用期) },
            { "待入职员工数量", raw.Count(e => e.State == PersonState.试用期 && e.HireDate < monthEnd.AddMonths(-3)) },
            { "待离职员工数量", 0 },
            { "待退休员工数量", retirementCount },
        };
        return data;
    }

    /// <summary>
    /// 计算指定日期时的年龄
    /// </summary>
    /// <param name="birthDate">出生日期</param>
    /// <param name="targetDate">目标日期</param>
    /// <returns>年龄</returns>
    private static int CalculateAgeAtDate(DateTime birthDate, DateTime targetDate)
    {
        int age = targetDate.Year - birthDate.Year;
        if (targetDate.Month < birthDate.Month ||
            (targetDate.Month == birthDate.Month && targetDate.Day < birthDate.Day))
        {
            age--;
        }

        return age;
    }

    /// <summary>
    /// 批量生成岗位分配申请
    /// </summary>
    /// <param name="ids">选中的人员档案ID数组</param>
    /// <returns>生成的岗位分配申请主表ID</returns>
    [HttpPost("BatchAssignJobs")]
    [ActionDescription("批量生成岗位分配申请")]
    [PreventDuplicateSubmit]
    public async Task<Result<Guid>> BatchAssignJobs(string[] ids)
    {
        var vm = Wtm.CreateVM<SysPersonBatchVm>();

        if (ids != null && ids.Any())
        {
            vm.Ids = ids;
        }
        else
        {
            return new Result<Guid>("请选择需要分配岗位的员工档案");
        }

        return await vm.BatchAssignJobsAsync();
    }
}